#ifndef _ZKRD522_C_
#define _ZKRD522_C_


#include "include/zkrd522.h"
#include "include/spi.h"
#include "include/delay.h"
#include "include/ca51f003_config.h"
#include "include/uart.h"
/**
 * @brief  set one the bit of a register
 * @param  reg: register
 * @param  mask : the bit tobe clear
 * @retval None
 */
void set_bit_mask(unsigned char reg, unsigned char mask) {
    unsigned char  tmp;
    tmp = spi_read_reg(reg);
    spi_write_reg(reg, tmp | mask);  // set bit mask
}
/**
 * @brief  set zero the bit of a register
 * @param  reg: register
 * @param  mask : the bit tobe clear
 * @retval None
 */
void clear_bit_mask(unsigned char reg, unsigned char mask) {
    unsigned char  tmp;
    tmp = spi_read_reg(reg);
    spi_write_reg(reg, tmp & ~mask);  // clear bit mask
}
/**
 * @brief  : the base api of transceive of reader chip. referenced all command
 * @param  pi : see the transceive_buffer struct
 * @retval 0: ok
 * @retval other: err or timeout.
 */
char pcd_com_transceive(struct transceive_buffer *pi)
{
	
	unsigned int delay_conut = 0;
	char status = 0;
	char reg_value = 0;
	spi_write_reg(fifolevel_reg, 0x80);                      //clear fifo data
	spi_write_reg(recstate_reg, 0x7F);                       //清接收状态寄存器
	spi_write_fifo(pi->mf_data,pi->mf_length);	 //把数据写入FIFO
//	uart_printf("%02x %02x",pi->mf_data[0],pi->mf_data[1]);
	spi_write_reg(command_reg, pi->mf_command | BIT7);  	//命令寄存器,正常模式下该寄存器最高位需置1

	if(PCD_AUTHENT == pi->mf_command)
	{
		 while((spi_read_reg(status2_reg) & 0x0c) != 0x08) 
     {
         delay_conut++;
         if(delay_conut >= 0x3000)
         {
					delay_conut = 0;
#if (NFC_DEBUG)
					uart_printf("authent error\r\n!");
#endif
					spi_write_reg(recstate_reg, 0x7F);
          return MI_AUTHERR;
         }
        }
        spi_write_reg(status2_reg, 0x08);    //清除认证状态标志位
        return MI_OK;	
	}
	else if(PCD_TRANSMIT == pi->mf_command)
	{
		spi_write_reg(recstate_reg, 0x7F);
		return MI_OK;
	}
	else
	{
		while((spi_read_reg(recstate_reg) & 0x01) != 0x01)       //读接收状态寄存器
		{
			delay_conut++;
			if((delay_conut >= 0x3000)||((spi_read_reg(recstate_reg) & 0x04) == 0x04) )//
			{
				delay_conut = 0;
#if (NFC_DEBUG)
				uart_printf("transceive_error\r\n!");
				uart_printf("recstate_reg:recstate_reg:%02x\r\n",spi_read_reg(recstate_reg));
#endif
				spi_write_reg(recstate_reg, 0x7F);
				return MI_ERR_RECEIVE;
			}
		}
		
		if(spi_read_reg(recstate_reg) & (BIT1))
		{
			pi->mf_length  = spi_read_reg(fifolevel_reg);                  //FIFO长度寄存器
			pi->mf_data[0] = spi_read_reg(collpos_reg);//获取冲突字节和比特的位置信息
			spi_read_fifo(&pi->mf_data[1],pi->mf_length);
			status = MI_COLL;
		}
		else
		{
			pi->mf_length  = spi_read_reg(fifolevel_reg);                  //FIFO长度寄存器
			spi_read_fifo(pi->mf_data,pi->mf_length);
			status = MI_OK;
		}
		spi_write_reg(recstate_reg, 0x7F);

#if (NFC_DEBUG)
		uart_printf("Current respone of cmd:");
		for(i = 0;i < pi->mf_length; i++ )
		{
			uart_printf("%02x ",pi->mf_data[i]);
		}
		uart_printf("\r\n");
#endif
	}
	return status;	
}
 /**
 * @brief  The rate between PCD and PICC
 * @param  rate:0x00,0x01,0x02,0x03;(106k-848k)
 * @para   waitpara: 0~14
 * @retval None
 */
void pcd_set_rate(unsigned char rate,unsigned char wait_param) {
    switch(rate) {
        case 0:
						clear_bit_mask(txmode_reg, BIT4 | BIT5 | BIT6);
            clear_bit_mask(rxmode_reg, BIT4 | BIT5 | BIT6);
						spi_write_reg(waitparam_reg, wait_param & 0x0f);	//帧等待寄存器,wait_param就是FWI
            break;
        case 1:
						clear_bit_mask(txmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(txmode_reg, BIT4);
            clear_bit_mask(rxmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(rxmode_reg, BIT4);
						spi_write_reg(waitparam_reg, wait_param & 0x0f);	//帧等待寄存器,wait_param就是FWI
            break;
        case 2:
            clear_bit_mask(txmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(txmode_reg, BIT5);
            clear_bit_mask(rxmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(rxmode_reg, BIT5);
						spi_write_reg(waitparam_reg, wait_param & 0x0f);	//帧等待寄存器,wait_param就是FWI
            break;
        case 3:
						clear_bit_mask(txmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(txmode_reg, BIT4 | BIT5);
            clear_bit_mask(rxmode_reg, BIT4 | BIT5 | BIT6);
            set_bit_mask(rxmode_reg, BIT4 | BIT5);
						spi_write_reg(waitparam_reg, wait_param & 0x0f);	//帧等待寄存器,wait_param就是FWI
            break;
        default:
						clear_bit_mask(txmode_reg, BIT4 | BIT5 | BIT6);
            clear_bit_mask(rxmode_reg, BIT4 | BIT5 | BIT6);
            break;
    }
}
char pcd_config(unsigned char type)
{
    if('A' == type)
    {
//			spi_write_reg(txmode_reg, 0x00);   							//配置发送编码格式typeA
//			spi_write_reg(rxmode_reg, 0x00);							//配置接收编码格式typeA
			spi_write_reg(rxgain_reg, 0x02);							//配置接收增益，0x00->最大，板级噪声较低时，可配置为最大，一般40db即可。
			spi_write_reg(svl_reg, 0x40);                              //SVL建议配置0x10或0x20或0x40
			spi_write_reg(modconductance_reg, 0x05);          			//MODCONDUCTANCE 凹槽载波调制深度 05
			spi_write_reg(cwconductance_reg, 0x09);     			//p_CWCONDUCTANCE (09
			spi_write_reg(txcontrol_reg, 0x1b);          				//TXCONTRL  100%调制  1b
			spi_write_reg(0x36,0x29);
			spi_write_reg(0x35,0x19);
			spi_write_reg(command_reg,0x81);
			uart_printf("txmode_reg:%02bx\r\n",spi_read_reg(txmode_reg));	
			uart_printf("rxmode_reg:%02bx\r\n",spi_read_reg(rxmode_reg));	
			uart_printf("rxgain_reg:%02bx\r\n",spi_read_reg(rxgain_reg));	
			uart_printf("svl_reg_value:%02bx\r\n",spi_read_reg(svl_reg));
			uart_printf("modconductance_reg_value:%02bx\r\n",spi_read_reg(modconductance_reg));
			uart_printf("cwconductance_reg_value:%02bx\r\n",spi_read_reg(cwconductance_reg));
			uart_printf("txcontrol_reg_value:%02bx\r\n",spi_read_reg(txcontrol_reg));


    }
    else if('B' == type)
    {
			spi_write_reg(txmode_reg, 0x03);   							//配置为ISO14443B协议
			spi_write_reg(rxmode_reg, 0x03); 
			spi_write_reg(rxgain_reg, 0x02);
			spi_write_reg(svl_reg, 0x20);
			spi_write_reg(modconductance_reg, 0x05);          			//MODCONDUCTANCE 载波凹槽调制深度，
			spi_write_reg(cwconductance_reg, 0x09);          			//CWCONDUCTANCE 发射功率组数
			spi_write_reg(txcontrol_reg, 0x0b);          				//TXCONTRL， 10%

    }
    else
    {
        return USER_ERROR;
    }
    return MI_OK;
}
//硬件计算CRC接口
char pcd_get_crc(unsigned char mode, unsigned char len, unsigned char *crc_src, unsigned char* crc_lsb, unsigned char* crc_msb)
{
    unsigned int i = 0;
    spi_write_fifo(crc_src,len);                    //写进FIFO要计算的crc的值
    spi_write_reg(crcpreset_reg, mode);                      //CRC配初值
    spi_write_reg(command_reg, 0x92);          		           //启动硬件计算CRC
		
    while((spi_read_reg(divirq_reg) & 0x04) != 0x04)        //crc计算计数器
    {
        i++;

        if(i >= 0x5000)
        {
            i = 0;
            return MI_COM_ERR;
        }
    }

    *crc_lsb = spi_read_reg(crclsb_reg);                     //CRC结果低8位
    *crc_msb = spi_read_reg(crcmsb_reg);                     //CRC结果高8位

    return 0;
}
#endif
